package gnss

import (
	"dgo/goutils/utils"
	"fmt"
)

var (
	hemi_prefix_buf = []byte{'$', 'B', 'I', 'N'}
)

type HemiBinDecoder struct {
	decodeStep int8
	msgid      uint16
	packl      uint16
	cache      utils.BytesBuilder
	OnBinPack  func(msgid uint16, packbuf []byte)
}

func NewHemiDecoder() *HemiBinDecoder {
	rval := &HemiBinDecoder{}
	return rval
}

func (this *HemiBinDecoder) StatusString() string {
	return fmt.Sprintf("msgid:%d,packl:%d, msgl:%d,decodestep:%d,cache:%s, buf:%s", this.msgid, this.packl, 8+int(this.packl)+2+2, this.decodeStep, this.cache.StatusString(),
		this.cache.BufAsHexStr(0, 8+int(this.packl)+2+2+10, ""))
}

func (this *HemiBinDecoder) InputByte(v byte) int {
	if this.decodeStep <= 0 {
		this.cache.Reset()
		this.decodeStep = 1
	}

	this.cache.WriteByte(v)
	l := this.cache.Len()

	if l <= 4 {
		idx := l - 1
		if this.cache.Byte(idx) != hemi_prefix_buf[idx] {
			this.decodeStep = -1
			return -1
		}
		return 0
	} else if l == 6 {
		this.msgid = this.cache.Uint16_LE(4)
	} else if l == 8 {
		this.packl = this.cache.Uint16_LE(6)
	} else {
		maxl := 8 + int(this.packl) + 2 + 2
		if l == maxl {
			if this.OnBinPack != nil {
				this.OnBinPack(this.msgid, this.cache.Bytes())
			}
			this.decodeStep = 0
			return 1
		} else if l > maxl { // 如果onBinPack发生Panic
			this.decodeStep = -1
			return -1
		}
	}

	return 0
}

func (this *HemiBinDecoder) InputBuf(buf []byte) {
	for i := 0; i < len(buf); i++ {
		this.InputByte(buf[i])
	}

}
